/**
 * 改编自ext.ux.treepicker
 * A Picker field that contains a grid panel on its popup, enabling selection of grid records.
 */
Ext.define('Ext.ux.GridCombobox', {
    extend: 'Ext.form.field.ComboBox',
    xtype: 'gridcombobox',

    uses: [
        'Ext.grid.Panel'
    ],
    config: {
        //选中行数据数组：displayTplData
        /**
         * 是否允许多选，默认false
         */
        multiSelect: false,
        /**
         * 是否允许编辑，默认false
         */
        editable: false,
        /**
         * 下拉内容是否与下拉控件宽度一致，默认false
         */
        matchFieldWidth: false,
        /**
         * @cfg {String} displayField
         * The field inside the model that will be used as the record's text.
         * Defaults to the default value of {@link Ext.grid.Panel}'s `displayField` configuration.
         */
        displayField: null,
        valueField: null,
        /**
         * 取值模式，row：将一行数据转换成string，赋值，默认模式：去valueField中显示列
         */
        valueMode: null,
        /**
         * @cfg {Array} columns
         * An optional array of columns for multi-column grids
         */
        columns: null,
        /**
         * @cfg {Ext.data.Store} store
         * A grid store that the grid picker will be bound to
         */
        store: null,
        /**
         * @cfg {Number} maxPickerHeight
         * 下拉表格高度. Defaults to 250.
         */
        pickerHeight: 250,
        /**
         * @cfg {Number} minPicekerWidth
         * 下拉表格宽度. Defaults to 500.
         */
        pickerWidth: 500,
        /**
         * @cfg {Number} minPickerHeight
         * The minimum height of the grid dropdown. Defaults to 50.
         */
        minPickerHeight: 50,
        /**
         * @cfg {Number} maxPickerHeight
         * The maximum height of the grid dropdown. Defaults to 1280.
         */
        maxPickerHeight: 1280,
        /**
         * @cfg {Number} minPicekerWidth
         * The minimum width of the grid dropdown. Defaults to 50.
         */
        minPickerWidth: 50,
        /**
         * @cfg {Number} minPicekerWidth
         * The minimum width of the grid dropdown. Defaults to 1920.
         */
        maxPickerWidth: 1920
    },

    /**
     * Creates and returns the grid panel to be used as this field's picker.
     */
    createPicker: function () {
        var me = this,
            picker = Ext.create('Ext.grid.Panel', {
                store: me.store,
                columns: me.columns,
                displayField: me.displayField,
                width: me.pickerWidth,
                height: me.pickerHeight,
                maxWidth: me.maxPickerWidth,
                minWidth: me.minPickerWidth,
                maxHeight: me.maxPickerHeight,
                minHeight: me.minPickerHeight,
                selModel: {
                    mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
                },
                resizable: true,
                floating: true,
                focusOnToFront: true
            }),
            view = picker.getView();
        me.mon(picker, {
            itemclick: me.onItemClick,//选中行时触发
            //refresh: me.onListRefresh,
            scope: me
        });

        me.mon(picker.getSelectionModel(), {
            selectionchange: me.onListSelectionChange,//选中行变换时触发
            scope: me
        });
        me.picker = picker;
        return picker;
    },

    /**
     * 行点击事件：下拉表格单选时执行赋值等操作
     * @param picker
     * @param record
     */
    onItemClick: function (picker, record, item, index) {
        /*
         * If we're doing single selection, the selection change events won't fire when
         * clicking on the selected element. Detect it here.
         */
        var me = this,
            selection = me.picker.getSelectionModel().getSelection(),
            valueField = me.valueField;

        if (!me.multiSelect && selection.length) {
            if (record.get(valueField) === selection[0].get(valueField)) {
                // Make sure we also update the display value if it's only partial
                me.displayTplData = [record.data];
                if (me.valueMode != null && me.valueMode == 'row') {
                    me.setRawValue(Ext.encode(record.data));
                } else {
                    me.setRawValue(me.getDisplayValue());
                }
                me.collapse();
            }
        }
        if (me.gridListeners && me.gridListeners.itemclick) {
            me.gridListeners.itemclick(me, me.picker, record, item, index);
        }
    },
    /**
     * 拷贝下拉框的setValue方法，并覆盖
     * @param value
     * @returns {*}
     */
    setValue: function (value) {
        var me = this;

        // Value needs matching and record(s) need selecting.
        if (value != null) {
            return me.doSetValue(value);
        }
        // Clearing is a special, simpler case.
        else {
            me.suspendEvent('select');
            me.valueCollection.beginUpdate();
            me.pickerSelectionModel.deselectAll();
            me.valueCollection.endUpdate();
            me.lastSelectedRecords = null;
            me.resumeEvent('select');
        }
    },
    /**
     * 选中行变换事件：单选/多选变换选中行时触发
     * @param list
     * @param selectedRecords
     */
    onListSelectionChange: function (list, selectedRecords) {
        var me = this,
            isMulti = me.multiSelect,
            hasRecords = selectedRecords.length > 0;
        // Only react to selection if it is not called from setValue, and if our list is
        // expanded (ignores changes to the selection model triggered elsewhere)
        if (!me.ignoreSelection && me.isExpanded) {
            if (!isMulti) {
                Ext.defer(me.collapse, 1, me);
            }
            /*
             * Only set the value here if we're in multi selection mode or we have
             * a selection. Otherwise setValue will be called with an empty value
             * which will cause the change event to fire twice.
             */
            if (isMulti || hasRecords) {
                me.setValue(selectedRecords, false);
            }
            if (hasRecords) {
                me.fireEvent('select', me, selectedRecords);
            }
            me.inputEl.focus();
        }
    }
});

